/** 
 * @file Intervalos.java
 * 
 * @author Luis Ernesto Carrera Retana
 * @date 2009-11-29
 */

package estadistec.logica.tabla;

import estadistec.logica.tipos.TipoValor;
import estadistec.logica.tipos.TipoIntervalo;
import estadistec.logica.tipos.Intervalo;

import estadistec.excepciones.ExcepcionFormatoNumeros;

/** 
 * Se incluye para formatear la conversión a string de los números.
 */
import java.text.DecimalFormat;

/** 
 * Clase para los valores de tipo Intervalo.
 **/
public class MIntervalo extends Medida<Intervalo> {

	/** 
	 * Guarda el número de decimales.
	 */
	private int _noDecimales;

	/** 
	 * Guarda el formato para convertir a un string.
	 */
	private DecimalFormat _miFormato;

	/** 
	 * Constructor. 
	 *
	 * Para las excepciones @see estadistec.logica.tipos.Valores#Valores
	 */
	public MIntervalo (String nombre, LTabla padre, Long llave) 
	{
		_noDecimales = 2;
		_miFormato = new DecimalFormat("#####0.00");
		this.setNombre(nombre);
		this._lTabla = padre;
		this._llave = new Long(llave);
	}

	public void setValor (Intervalo valor) {
		this._valor = new Intervalo(valor);
	};

	/** 
	 * @see estadistec.logica.tipos.Valores#getTipo
	 */
	public TipoValor getTipo() {
		return TipoValor.INTERVALO;
	}

	/** 
	 * @see estadistec.logica.tipos.Valores#setNoDecimales
	 */
	public void setNoDecimales (int n) {
		this._noDecimales = n;
		char punto = '.';
		if ( n == 0 )
			punto = 0;
		_miFormato.applyPattern("#####0" + punto + "000000".substring(0,n));
	}

	/** 
	 * @see estadistec.logica.tipos.Valores#getNoDecimales
	 */
	public int getNoDecimales () {
		return this._noDecimales;
	}

	public Intervalo _obtenerValor(String texto) {
		return obtenerValor(texto);
	}

	/** 
	 * Método que convierte de un String que representa un flotante
	 * a un valor de tipo Intervalo. Utiliza el constructor de \c Float
	 * y atrapa la excepción de \c NumberFormatException, para lanzar
	 * \c ExcepcionFormatoNumeros.
	 * 
	 * @param texto String que representa al posible valor.
	 *
	 * @throws ExepcionFormatoValor En caso de que java no pueda
	 * convertir a un flotante.
	 */
	static public Intervalo obtenerValor (String texto)  
		throws ExcepcionFormatoNumeros
	{
		TipoIntervalo tipo;
		Float fIzq, fDer;
		texto = texto.trim();
		int indComa;
		int n = texto.length();
		if (texto.charAt(0) == ']' || texto.charAt(0) == '(' )
			if (texto.charAt(n-1) == '[' || texto.charAt(n-1) == ')')
				tipo = TipoIntervalo.ABIERTO;
			else if (texto.charAt(n-1) == ']')
				tipo = TipoIntervalo.ABI_IZQ;
			else
				throw new ExcepcionFormatoNumeros("Se esperaba '[', ']' o ')' al final.");
		else if (texto.charAt(0) == '[') {
			if (texto.charAt(n-1) == ']')
				tipo = TipoIntervalo.CERRADO;
			else if (texto.charAt(n-1) == '[' || texto.charAt(n-1) == ')')
				tipo = TipoIntervalo.ABI_DER;
			else
				throw new ExcepcionFormatoNumeros("Se esperaba '[', ']' o ')' al final.");
		} else
			throw new ExcepcionFormatoNumeros("Se esperaba '[', ']' o '(' al inicio.");
		indComa = texto.indexOf(',');
		try {
			fIzq = new Float(texto.substring(1, indComa));
		} catch (NumberFormatException e) {
			throw new ExcepcionFormatoNumeros("Se esperaba un flotante: " 
					+ texto.substring(1, indComa));
		}
		try {
			fDer = new Float(texto.substring(indComa + 1, n-1));
		} catch (NumberFormatException e) {
			throw new ExcepcionFormatoNumeros("Se esperaba un flotante: " 
				+ texto.substring(indComa + 1, n - 1));
		}
		return new Intervalo(tipo, fIzq, fDer);
	}

	public String _obtenerTexto(Intervalo valor) {
		return (obtenerTexto(valor, this._miFormato));
	}

	/** 
	 * Convierte un valor de tipo Float a un string.
	 */
	static public String obtenerTexto(
			Intervalo valor, DecimalFormat formato) 
	{
		String texto = formato.format(valor.getValorIzq());
		texto += ", ";
		texto += formato.format(valor.getValorDer());
		switch(valor.getTipo()) {
			case ABIERTO:
				texto = ("]" + texto + "[");
				break;
			case CERRADO:
				texto = ("[" + texto + "]");
				break;
			case ABI_IZQ:
				texto = ("]" + texto + "]");
				break;
			case ABI_DER:
				texto = ("[" + texto + "[");
				break;
		};
		return texto;
	}

}
